package com.tianji.aigc.memory;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource;
import org.aspectj.weaver.ast.Var;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.messages.Message;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;
import java.util.Set;

// 基于Redis实现ChatMemeoryRepository
public class RedisChatMemoryRepository implements ChatMemoryRepository,MyChatMemoryRepository{

    // 默认redis中key的前缀
    public static final String DEFAULT_PREFIX = "CHAT:";

    // 注入redis模板，进行redis的操作
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 查询所有的对话id
    @Override
    public List<String> findConversationIds() {
        Set<String> keys = stringRedisTemplate.keys(DEFAULT_PREFIX + "*");
        return ListUtil.toList(keys);
    }

    // 根据对话id查询Message列表
    @Override
    public List<Message> findByConversationId(String conversationId) {
        //1. 先找到当前会话id所对应的redisKey
        String redisKey = getKey(conversationId);
        //2. 在redis中查询数据
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(redisKey);
        //3. 获取列表中的全部数据
        List<String> list = listOps.range(0, -1);
        //4. 将列表中的数据转换为Message对象，并返回
        return CollStreamUtil.toList(list,MessageUtil::toMessage);
    }

    // 保存Message列表数据
    @Override
    public void saveAll(String conversationId, List<Message> messages) {
        //1. Hutool 的断言工具，确保 messages 不为 null 或空，否则抛出异常。
        Assert.notEmpty(messages, "消息列表不能为空");
        //2. 获取 Redis 的键，CHAT:对话id
        String redisKey = getKey(conversationId);
        //3. 获取 Redis的List列表操作对象
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(redisKey);
        //4. 保存数据时，会传入全部的消息数据，包括之前的数据，所以需要先删除之前的数据，再添加新的数据
        deleteByConversationId(conversationId);
        //5. 将序列化后的字符串推入 Redis List 的右侧（尾部）
        messages.forEach(message -> listOps.rightPush(MessageUtil.toJson( message)));
    }

    // 根据对话id删除所有历史消息
    @Override
    public void deleteByConversationId(String conversationId) {
        String redisKey = getKey(conversationId);
        stringRedisTemplate.delete(redisKey);
    }

    // 一个私有工具方法，根据前缀和对话ID生成完整的 Redis Key
    private String getKey(String conversationId) {
        return DEFAULT_PREFIX + conversationId;
    }

    /**
     * 删去后面两个数据
     */
    @Override
    public void optimization(String conversationId) {
        String key = getKey(conversationId);
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(key);
        // 从Redis列表右侧弹出2个元素
        listOps.rightPop(2);
    }


}